package com.wenwen.social.domain.service.Impl;

import com.wenwen.social.constant.LikeKeyContent;
import com.wenwen.social.domain.model.MessageLikes;
import com.wenwen.social.domain.service.MessageLikesService;
import com.wenwen.social.util.PageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class MessageLikesServiceImpl implements MessageLikesService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void addLikes(MessageLikes likes) {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.add(LikeKeyContent.MESSAGE_LIKE.getKey(likes.getMsgId()), likes.getUid(), likes.getCreatetime().getTime());

    }

    @Override
    public void cancelLikes(MessageLikes likes) {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.remove(LikeKeyContent.MESSAGE_LIKE.getKey(likes.getMsgId()), likes.getUid(), likes.getMsgId());
    }

    @Override
    public List<MessageLikes> getLikes(Long msgId, Long startTime, Integer limit) {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        Set<ZSetOperations.TypedTuple> resultSet = zSetOperations.reverseRangeByScoreWithScores(LikeKeyContent.MESSAGE_LIKE.getKey(msgId),
                0D, (double) startTime, 0L, limit.longValue());
        if (Objects.isNull(resultSet) || resultSet.isEmpty()) {
            return new ArrayList<MessageLikes>();
        }

        return buildGetLikesResult(msgId, resultSet);
    }

    @Override
    public List<MessageLikes> getLikes(Long msgId, Integer pageNum, Integer pageSize) {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        PageUtil pageUtil = new PageUtil(pageNum, pageSize);
        Set<ZSetOperations.TypedTuple> resultSet = zSetOperations.reverseRangeWithScores(LikeKeyContent.MESSAGE_LIKE.getKey(msgId), pageUtil.getStartNum(), pageUtil.getEndNum());
        if (resultSet == null || resultSet.isEmpty()) {
            return new ArrayList<>();
        }

        return buildGetLikesResult(msgId, resultSet);
    }

    @Override
    public boolean existLikes(Long uid, Long messageId) {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        Double score = zSetOperations.score(LikeKeyContent.MESSAGE_LIKE.getKey(messageId), uid);
        if (score != 0 && score > 0L) {
            return true;
        }
        return false;
    }

    @Override
    public Map<Long, MessageLikes> existLikes(Long uid, List<Long> messageId) {
        return null;
    }


    private List<MessageLikes> buildGetLikesResult(Long msgId, Set<ZSetOperations.TypedTuple> resultSet) {
        return resultSet.stream().map(new Function<ZSetOperations.TypedTuple, MessageLikes>() {
            @Override
            public MessageLikes apply(ZSetOperations.TypedTuple typedTuple) {

                MessageLikes messageLikes = new MessageLikes();

                messageLikes.setCreatetime(new Date(typedTuple.getScore().longValue()));

                messageLikes.setUid(((Integer)typedTuple.getValue()).longValue());

                messageLikes.setMsgId(msgId);

                return messageLikes;
            }
        }).collect(Collectors.toList());
    }

}
